package com.web.pay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.WebUtils;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.google.gson.JsonObject;
import com.xkk.utils.GSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * 蚂蚁金服 支付
 *
 * @author xukk
 * @date 2017/7/4
 */
@Slf4j
public class AliPayManage {
    public static AliPayManage mg = new AliPayManage();

    /**
     * 扫码支付
     * @param payCodeDto
     * @return
     */
    public PayResponse aliPayCode(AliPayDto payCodeDto) {
        AlipayClient alipayClient = new DefaultAlipayClient(payCodeDto.getPayUrl(), payCodeDto.getPayAppid(), payCodeDto.getPaySelfSecret(), "json", "utf-8", payCodeDto.getPayPublicSecret2(), "RSA2");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        if (payCodeDto.getNotifyUrl() != null)
            request.setNotifyUrl(payCodeDto.getNotifyUrl());
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("out_trade_no", payCodeDto.getOutTradeNo());
        jsonObject.addProperty("total_amount", payCodeDto.getTotalAmount());
        jsonObject.addProperty("subject", payCodeDto.getSubject());
        if (payCodeDto.getSellerId() != null)
            jsonObject.addProperty("seller_id", payCodeDto.getSellerId());
        if (payCodeDto.getBody() != null)
            jsonObject.addProperty("body", payCodeDto.getBody());
        String content = jsonObject.toString();
        log.info("ali payCode data->{}", content);
        request.setBizContent(content);
        AlipayTradePrecreateResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            log.warn("ali payCode AlipayApiException error->{}", e.getMessage());
            return PayResponse.custom().failure(e.getMessage());
        } catch (Exception e) {
            log.warn("ali payCode AlipayApiException error->{}", e.getMessage());
            return PayResponse.custom().failure(e.getMessage());
        }
        log.info("ali payCode response->{}", GSONUtil.toJson(response));
        if (response.isSuccess()) {
            return PayResponse.custom().addParams(response).ok();
        } else {
            return PayResponse.custom().failure(response.getSubMsg());
        }
    }

    /**
     * APP支付
     * @param payCodeDto
     * @return
     */
    public PayResponse aliPayApp(AliPayDto payCodeDto) throws Exception{
        AlipayClient alipayClient = new DefaultAlipayClient(payCodeDto.getPayUrl(), payCodeDto.getPayAppid(), payCodeDto.getPaySelfSecret(), "json", "utf-8", payCodeDto.getPayPublicSecret2(), "RSA2");
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
       /* if (StringUtils.isNotBlank(payCodeDto.getBody()))
            model.setBody(payCodeDto.getBody());
        if(StringUtils.isNotBlank(payCodeDto.getSellerId()))
            model.setSellerId(payCodeDto.getSellerId());
        model.setSubject(payCodeDto.getSubject());
        model.setOutTradeNo(payCodeDto.getOutTradeNo());
        if (StringUtils.isNotBlank(payCodeDto.getTimeOutExpress()))
            model.setTimeoutExpress(payCodeDto.getTimeOutExpress());
        request.setNotifyUrl(payCodeDto.getNotifyUrl());
        if (StringUtils.isNotBlank(payCodeDto.getProductCode()))
            model.setProductCode(payCodeDto.getProductCode());
        else model.setProductCode("QUICK_MSECURITY_PAY");

        model.setTotalAmount(payCodeDto.getTotalAmount());
        log.info("ali appCode data->{}", GSONUtil.toJson(model));
        request.setBizModel(model);*/

        model.setBody(payCodeDto.getBody());
        model.setSubject(payCodeDto.getSubject());
        model.setOutTradeNo(payCodeDto.getOutTradeNo());
        model.setTimeoutExpress(payCodeDto.getTimeOutExpress());
        model.setTotalAmount(payCodeDto.getTotalAmount());
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(payCodeDto.getNotifyUrl());
        log.info("支付宝请求request："+GSONUtil.toJson(request));
        AlipayTradeAppPayResponse response = null;
        try {
            response = alipayClient.sdkExecute(request);
        } catch (AlipayApiException e) {
            log.warn("ali appCode AlipayApiException error->{}", e.getErrMsg());
            return PayResponse.custom().failure(e.getErrMsg());
        } catch (Exception e) {
            log.warn("ali appCode Exception error->{}", e.getMessage());
            return PayResponse.custom().failure(e.getMessage());
        }
        log.info("ali appCode response->{}", GSONUtil.toJson(response));
        if (response.isSuccess()) {
            return PayResponse.custom().addParams(response).ok();
        } else {
            return PayResponse.custom().failure(response.getSubMsg());
        }
    }

    /**
     * 取消支付
     * @param payCodeDto
     * @return
     */
    public PayResponse aliCancel(AliPayDto payCodeDto) {
        AlipayClient alipayClient = new DefaultAlipayClient(payCodeDto.getPayUrl(), payCodeDto.getPayAppid(), payCodeDto.getPaySelfSecret(), "json", "utf-8", payCodeDto.getPayPublicSecret(), "RSA");
        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        if (StringUtils.isBlank(payCodeDto.getTradeNo()) && StringUtils.isBlank(payCodeDto.getOutTradeNo())) {
            return PayResponse.custom().failure("tradeNo,outTradeNo 不能同时为空");
        }
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("out_trade_no", payCodeDto.getOutTradeNo());
        jsonObject.addProperty("trade_no", payCodeDto.getTradeNo());
        request.setBizContent(jsonObject.toString());
        AlipayTradeCancelResponse response = null;
        try {
            response = alipayClient.execute(request);
            log.info("ali cancel response->{}", GSONUtil.toJson(response));
        } catch (AlipayApiException e) {
            log.warn("ali cancel AlipayApiException error->{}", e.getErrMsg());
            return PayResponse.custom().failure(e.getErrMsg());
        } catch (Exception e) {
            log.warn("ali cancel AlipayApiException error->{}", e.getMessage());
            return PayResponse.custom().failure(e.getMessage());
        }
        if (response.isSuccess()) {
            return PayResponse.custom().addParams(response).ok();
        } else {
            return PayResponse.custom().failure(response.getSubMsg());
        }
    }

    /**
     * 退款
     * @param payCodeDto
     * @return
     */
    public PayResponse aliRefund(AliPayDto payCodeDto) {
        AlipayClient alipayClient = new DefaultAlipayClient(payCodeDto.getPayUrl(), payCodeDto.getPayAppid(), payCodeDto.getPaySelfSecret(), "json", "utf-8", payCodeDto.getPayPublicSecret(), "RSA2");
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        if (StringUtils.isBlank(payCodeDto.getRefundAmount())) {
            return PayResponse.custom().failure("refundAmount 不为空");
        }
        if (StringUtils.isNoneBlank(payCodeDto.getOutTradeNo(), payCodeDto.getTradeNo())) {
            return PayResponse.custom().failure("out_trade_no,trade_no 两者不能同时为空");
        }
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("out_trade_no", payCodeDto.getOutTradeNo());
        jsonObject.addProperty("trade_no", payCodeDto.getTradeNo());
        jsonObject.addProperty("refund_amount", payCodeDto.getRefundAmount());
        jsonObject.addProperty("refund_reason", payCodeDto.getRefundReason());
        String content = jsonObject.toString();
        log.info("ali refund data->{}", content);
        request.setBizContent(content);
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
            log.info("ali refund response->{}", GSONUtil.toJson(response));
        } catch (AlipayApiException e) {
            log.warn("ali refund AlipayApiException error->{}", e.getErrMsg());
            return PayResponse.custom().failure(e.getErrMsg());
        } catch (Exception e) {
            log.warn("ali refund Exception error->{}", e.getMessage());
            return PayResponse.custom().failure(e.getMessage());
        }
        if (response.isSuccess()) {
            return PayResponse.custom().addParams(response).ok();
        } else {
            return PayResponse.custom().failure(response.getSubMsg());
        }
    }

    /**
     * 校验Url 返回值
     *
     * @param payCodeDto
     * @return
     */
    public PayResponse aliValid(AliPayDto payCodeDto) {
        Map map = null;
        if (payCodeDto.getJson() != null) {
            map = WebUtils.splitUrlQuery( WebUtils.decode( payCodeDto.getJson() ) );
        }else{
            map = payCodeDto.getMap();
        }
        log.info("ali_notify_result_valid map:{}", map);
        String publicSecret = null;
        if (map.get("sign_type").equals("RSA2")) {
            publicSecret = payCodeDto.getPayPublicSecret2();
        }else {
            publicSecret = payCodeDto.getPayPublicSecret();}
        try {
            if (AlipaySignature.rsaCheckV1(map, publicSecret, "utf-8", map.get("sign_type").toString())) {
                return PayResponse.Map(map).ok();
            } else {
                return PayResponse.custom().failure("ali 校验失败!");
            }
        } catch (AlipayApiException e) {
            log.warn("AlipayApiException 错误:{}", e.getErrMsg());
            return PayResponse.custom().failure(e.getErrMsg());
        }
    }

    //查询交易订单支付结果

    public AlipayTradeQueryResponse tradeQuery(AliPayDto payCodeDto ) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(payCodeDto.getPayUrl(), payCodeDto.getPayAppid(), payCodeDto.getPaySelfSecret(), "json", "utf-8", payCodeDto.getPayPublicSecret2(), "RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent("{\"out_trade_no\":\""+payCodeDto.getOutTradeNo()+"\"}");
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return  response;
    }

}
